#!/bin/bash

source "./lib/format_log.sh"

#检查有无包
function grep_rpm() {
    for arg in "$@"; do
        if [[ ${arg} =~ ^[a-zA-Z0-9-]+$ ]]; then
            rpm -qa | grep "${arg}"
            if [ "$?" == 0 ]; then
                #rpm -qa | grep "${arg}" | tee -a "${OUTPUT_FILE}"
                log_title "已安装${arg}包：rpm -qa | grep ${arg}"
            else
                log_error "未安装${arg}：rpm -qa | grep ${arg}"
            fi
        fi
    done

}

#引用外部包列表来检查包是否安装service_rpm.txt
#执行脚本与data_rpm.txt目录在同一级
function sv_name_rpm() {
    local sv_name="$1"
    local service_rpm="./data/service_rpm.txt"
    while IFS=':' read -r service packages; do
        #packages=$(echo "${packages}" | tr -d '\n')
        case "$service" in
        ${sv_name})
            for package in $packages; do
                grep_rpm "$package"
            done
            ;;
        *) ;;
        esac
    done <"${service_rpm}"
}
#执行脚本与data_rpm.txt目录相差一级
function other_name_rpm() {
    local sv_name="$1"
    local data_rpm="../data/data_rpm.txt"
    while IFS=':' read -r service packages; do
        #packages=$(echo "${packages}" | tr -d '\n')
        case "$service" in
        ${sv_name})
            for package in $packages; do
                grep_rpm "$package"
            done
            ;;
        *) ;;
        esac
    done <"${data_rpm}"
}

#目前的策略是让用户自己决定是否下载包
# function install_rpm(){
#     local yum_install="yum install "
#     for arg in "$@"; do
#         "${yum_install}" "${arg}"  -y
#         if [ "$?" == 0 ];then
#             log_title "已安装${arg}包"
#         else
#             log_ret "安装${arg}包失败" "TCONF"
#         fi
#     done
# }

#服务停止
function st_stop() {
    local st_start="systemctl stop"
    local st_stauts="systemctl status"
    for arg in "$@"; do
        log_title "停止${arg}服务"
        log_title "${st_start} ${arg}"
        systemctl stop "${arg}"
        if [[ "$?" == 0 ]]; then
            log_title "停止${arg}服务成功"
        else
            log_ret "停止${arg}服务失败" "TFAIL"
        fi
        log_title "${st_status} ${arg}"
        systemctl status "${arg}" | tee -a "${OUTPUT_FILE}"
    done
}

#服务启动、服务状态
function st_sv() {
    local st_start="systemctl restart"
    local st_stauts="systemctl status"
    for arg in "$@"; do
        log_title "启动${arg}服务：${st_start} ${arg}"
        systemctl restart "${arg}"
        if [[ "$?" == 0 ]]; then
            log_title "启动${arg}服务成功：${st_status} ${arg}"
            systemctl status "${arg}" | tee -a "${OUTPUT_FILE}"
        else
            log_error "启动${arg}服务失败：${st_status} ${arg}"
            systemctl status "${arg}" | tee -a "${OUTPUT_FILE}"
        fi

    done
}

#停止防火墙服务
function stop_fw() {
    local packages=("firewalld")
    for i in "${packages[@]}"; do
        st_stop "${i}"
    done
}

#自启动服务
function enable_sv() {
    local st_enable="systemctl enable"
    for arg in "$@"; do
        log_title "自启动${arg}服务：${st_enable} ${arg}"
        systemctl enable "${arg}"
        if [[ "$?" == 0 ]]; then
            log_title "自启动${arg}服务成功：${st_enable} ${arg}"
        else
            log_error "自启动${arg}服务失败：${st_enable} ${arg}"
        fi

    done
}

#临时关闭se
function stop_se() {
    log_title "临时关闭se：setenforce 0"
    setenforce 0
}

#移动或重命名单个文件
function mv_file() {
    local file1="$1"
    local file2="$2"
    log_title "备份文件：mv ${file1} ${file2}"
    mv ${file1} ${file2}
}

#备份单个文件或目录
function cp_file() {
    local file1="$1"
    local file2="$2"
    log_title "替换文件：cp ${file1} ${file2}"
    cp -r ${file1} ${file2}
}

#删除文件或目录
function rm_file_dir() {
    for arg in "$@"; do
        rm -rf "${arg}"
        if [[ "$?" == 0 ]]; then
            log_title "已删除${arg}"
        else
            log_error "未删除${arg}，请清理"
        fi
    done
}

#给用户设置密码kylin.2023
function set_pw() {
    local user1="$1"
    echo "kylin.2023" | passwd --stdin "${user1}"
}

#创建目录
function mk_dir() {
    local dir="$1"
    mkdir -p "${dir}"
}

#删除用户
function del_user() {
    local user="$1"
    userdel -r "${user}"
    if [[ "$?" == 0 ]]; then
        log_title "成功删除${user}"
    fi
}

#查看文件或目录
function ls_file_dir() {
    local file="$1"
    ls -lhda "${file}"
}

#配置用户免密登录
function ssh_auto() {
    if [[ $# -ne 3 ]]; then
        log_error "请检查免密登录参数是否正确！"
    fi
    local user_name_ssha="$1"
    local ip_ssha="$2"
    local pass_word_ssha="$3"

    local rsapath_ssha="${HOME}/.ssh"
    local rsafile_ssha="id_rsa"
    # 公钥文件
    local rsapub_file_ssha="${rsapath_ssha}/${rsafile_ssha}.pub"

    # 密钥对不存在则创建密钥
    [[ ! -f "$rsapub_file_ssha" ]] && ssh-keygen -t rsa -N '' -f ${rsapath_ssha}/id_rsa -q

    ssh -o PasswordAuthentication=no -o StrictHostKeyChecking=no -o PreferredAuthentications=publickey "${user_name_ssha}"@"${ip_ssha}" "date" &>/dev/null
    if [[ $? != 0 ]]; then
        which expect &>/dev/null
        if [ $? -ne 0 ]; then
            log_error "不存在命令: expect . 所以无法为用户 ${user_name_ssha} 配置免密登录"
            log_error "请手动安装expect命令相关包，或者手动配置root 对于用户 ${user_name_ssha} 的免密登录"
        fi
    fi
    # 配置免密登录
    expect &>/dev/null <<-EOF
	spawn ssh-copy-id -i $rsapub_file_ssha $user_name_ssha@$ip_ssha
	expect {
		"yes/no" { send "yes\n";exp_continue}
		"password" { send "$pass_word_ssha\n"}
	}
	expect eof
	EOF

    ssh -o PasswordAuthentication=no -o StrictHostKeyChecking=no -o PreferredAuthentications=publickey "${user_name_ssha}"@"${ip_ssha}" "date"
    if [[ $? == 0 ]]; then
        log_title "${user_name_ssha}用户已配置免密登录"
    else
        log_error "配置免密登录失败，请验证下列参数是否正确 ip=${ip_ssha} user=${user_name_ssha} passwd=${pass_word_ssha}"
    fi
}

#免密登录后输入命令
function ssh_auto_cmd() {
    local user_name_ssha="$1"
    local ip_ssha="$2"
    local auto_cmd="$3"
    if [[ $# -ne 3 ]]; then
        log_error "请检查免密登录执行命令功能的参数是否正确！"
    fi
    # 禁止打印输出
    ssh -t -t -q "${user_name_ssha}"@"${ip_ssha}" "${auto_cmd}"
}

#自定义结果
function output_define() {
    local assert_flag="$1"
    return "${assert_flag}"
}

## TODO: 结果断言，0->成功，其他->失败。
#  In  : $1 => log
#        $2 => 是否退出测试，False->不退出,其他->退出。默认为true退出程序
#        $3 => 结果是否反转,yes->反转,no->不反转,默认为no不反转.(TPASS->TFAIL ,TFAIL-TPASS)
function title_assert() {
    local ret_toolslib="$?"
    local logstr_toolslib=""
    local exitflag_toolslib="true"
    local reverse_toolslib="no"

    if [[ $# -eq 0 ]]; then
        true
    elif [[ $# -eq 1 ]]; then
        logstr_toolslib="$1"
    elif [[ $# -eq 2 ]]; then
        logstr_toolslib="$1"
        exitflag_toolslib="$2"
    elif [[ $# -eq 3 ]]; then
        logstr_toolslib="$1"
        exitflag_toolslib="$2"
        reverse_toolslib="$3"
    else
        log_error "result_assert :invalid option -- $*($#)"
        # 退出
        exit 1
    fi

    #自定义反转结果
    if [[ "Z${reverse_toolslib}" == "Zyes" && "Z${ret_toolslib}" == "Z0" ]]; then
        ret_toolslib=${TFAIL}
    elif [[ "Z${reverse_toolslib}" == "Zyes" && "Z${ret_toolslib}" != "Z0" ]]; then
        ret_toolslib=${TPASS}
    elif [[ "Z${reverse_toolslib}" != "Zyes" && "Z${ret_toolslib}" == "Z0" ]]; then
        ret_toolslib=${TPASS}
    else
        ret_toolslib=${TFAIL}
    fi

    #根据结果输出日志
    if [[ "${ret_toolslib}" -eq ${TPASS} ]]; then
        # 成功
        log_title "${logstr_toolslib}"
        return ${TPASS}
    else
        # 失败
        log_error "${logstr_toolslib}"
        return ${TFAIL}
    fi

    if [[ "Z${exitflag_toolslib}" == "ZFalse" ]]; then
        # 继续执行
        return ${ret_toolslib}
    else
        # 退出
        exit 1
    fi
}

## TODO: 结果断言，0->成功，其他->失败。
#  In  : $1 => log
#        $2 => 是否退出测试，False->不退出,其他->退出。默认为true退出程序
#        $3 => 结果是否反转,yes->反转,no->不反转,默认为no不反转.(TPASS->TFAIL ,TFAIL-TPASS)
function ret_assert() {
    local ret_toolslib="$?"
    local logstr_toolslib=""
    local exitflag_toolslib="true"
    local reverse_toolslib="no"

    if [[ $# -eq 0 ]]; then
        true
    elif [[ $# -eq 1 ]]; then
        logstr_toolslib="$1"
    elif [[ $# -eq 2 ]]; then
        logstr_toolslib="$1"
        exitflag_toolslib="$2"
    elif [[ $# -eq 3 ]]; then
        logstr_toolslib="$1"
        exitflag_toolslib="$2"
        reverse_toolslib="$3"
    else
        log_error "result_assert :invalid option -- $*($#)"
        # 退出
        exit 1
    fi

    #自定义反转结果
    if [[ "Z${reverse_toolslib}" == "Zyes" && "Z${ret_toolslib}" == "Z0" ]]; then
        ret_toolslib=${TFAIL}
    elif [[ "Z${reverse_toolslib}" == "Zyes" && "Z${ret_toolslib}" != "Z0" ]]; then
        ret_toolslib=${TPASS}
    elif [[ "Z${reverse_toolslib}" != "Zyes" && "Z${ret_toolslib}" == "Z0" ]]; then
        ret_toolslib=${TPASS}
    else
        ret_toolslib=${TFAIL}
    fi

    #根据结果输出日志
    if [[ "${ret_toolslib}" -eq ${TPASS} ]]; then
        # 成功
        log_ret "${logstr_toolslib}" "TPASS"
        return ${TPASS}
    else
        # 失败
        log_ret "${logstr_toolslib}" "TFAIL"
        return ${TFAIL}
    fi

    if [[ "Z${exitflag_toolslib}" == "ZFalse" ]]; then
        # 继续执行
        return ${ret_toolslib}
    else
        # 退出
        exit 1
    fi
}
